package com.example.analysis.service.impl;

import com.example.analysis.controller.LoginController;
import com.example.analysis.domain.StudentInfo;
import com.example.analysis.dto.CourseScoreDto;
import com.example.analysis.dto.StudentPlatformScoreDto;
import com.example.analysis.entity.PageBean;
import com.example.analysis.entity.Student;
import com.example.analysis.dto.ClusterScoreDto;
import com.example.analysis.mapper.StudentDao;
import com.example.analysis.service.StudentService;
import com.example.analysis.utils.Response;
import com.example.analysis.vo.AssociationItemsVo;
import com.example.analysis.vo.AssociationRulesVo;
import com.example.analysis.vo.ClusterScoreVo;
import com.example.analysis.vo.TimeScoreVo;
import org.springframework.beans.factory.annotation.Autowired;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.*;

@Service
public class StudentServiceImpl implements StudentService {
    @Resource
    private StudentDao studentDao;
    @Autowired
    private LoginController loginController;


    @Override
    public Response<Student> insert(Student aStudent) {
        try {
            studentDao.insert(aStudent);
            return new Response<>(true, "Insert success", null);
        } catch (Exception e) {
            return new Response<>(false, "Insert failed: " + e.getMessage(), null);
        }
    }

    @Override
    public Response<Student> getById(String StudentId) {
        Student aStudent = studentDao.selectByPrimaryKey(StudentId);
        if (aStudent != null) {
            return new Response<>(true, "Success", aStudent);
        } else {
            return new Response<>(false, "Administration not found", null);
        }
    }

    @Override
    public Response<List<TimeScoreVo>> getTimeScoreSet(String classId, String subId) {
        System.out.println(classId);
        System.out.println(subId);
        System.out.println(studentDao.getTimeScoreSet(classId, subId));
        List<TimeScoreVo> timeScoreVo = studentDao.getTimeScoreSet(classId, subId);

        if (!timeScoreVo.isEmpty()) {
            return new Response<>(true, "Success", timeScoreVo);
        } else {
            return new Response<>(false, "Administration not found", null);
        }
    }

    //    @Override
//    public Response<Student> getByName(String StudentName) {
//
//    }


    /**
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public PageBean getAll(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<StudentInfo> studentList=studentDao.getAll();
        Page p=(Page) studentList;
        long total=p.getTotal();
        List result=p.getResult();
        PageBean pageBean=new PageBean();
        pageBean.setTotal(total);
        pageBean.setRows(result);//返回总条数和具体数据
        return pageBean;
    }


    // 定义项集编码常量
    private static final int COURSE_HIGH = 1;     // 课程分数 大于
    private static final int COURSE_LOW = 0;      // 课程分数 小于
    private static final int EVAL_HIGH = 2;       // 学生评教分数 大于
    private static final int EVAL_LOW = 3;        // 学生评教分数 小于
    private static final int EVAL_HIGH_TEA = 4;   // 督导评教分数 大于
    private static final int EVAL_LOW_TEA = 5;    // 督导评教分数 小于
    private static final int HIGH1 = 6;    // 通识教育分数
    private static final int HIGH2 = 7;    // 学科教育分数
    private static final int HIGH3 = 8;    // 专业课程分数

    private static List<AssociationItemsVo> calculateRulesItems(List<Set<Integer>> transactions) {
        int totalTransactions = transactions.size();
        System.out.println("总样本数: " + totalTransactions + " 个学生\n");

        // ===================================================================
        // 一、项集支持度计算
        // ===================================================================
        Map<Set<Integer>, Integer> itemSetCounts = new HashMap<>();

        // 预定义所有可能的单项和双项组合
        List<Set<Integer>> possibleItemSets = Arrays.asList(
                Set.of(COURSE_HIGH), Set.of(COURSE_LOW),
                Set.of(EVAL_HIGH), Set.of(EVAL_LOW),
                Set.of(COURSE_HIGH, EVAL_HIGH),
                Set.of(COURSE_HIGH, EVAL_LOW),
                Set.of(COURSE_LOW, EVAL_HIGH),
                Set.of(COURSE_LOW, EVAL_LOW),
                Set.of(COURSE_HIGH, EVAL_LOW)
        );

        // 计算每个项集的支持度计数
        for (Set<Integer> itemSet : possibleItemSets) {
            int count = 0;
            for (Set<Integer> transaction : transactions) {
                if (transaction.containsAll(itemSet)) {
                    count++;
                }
            }
            itemSetCounts.put(itemSet, count);
        }

        List<AssociationItemsVo> associationItemsVoList = new ArrayList<>();
        itemSetCounts.forEach((itemSet, count) -> {
            AssociationItemsVo associationItemsVo = new AssociationItemsVo();
            int index = 0;
            for (int item : itemSet) {
                if (index == 0) {
                    associationItemsVo.setFirstItem(item);
                    ++index;
                } else if(index == 1) {
                    associationItemsVo.setSecondItem(item);
                    ++index;
                }
            }
            associationItemsVo.setCount(count);
            associationItemsVoList.add(associationItemsVo);
        });


        // 打印支持度报表
        System.out.println("===================== 项集支持度分析 =====================");
        System.out.printf("%-30s %-15s %-15s%n", "项集描述", "出现次数", "支持度");
        itemSetCounts.forEach((itemSet, count) -> {
            String description = parseItemSet(itemSet);
            System.out.printf("%-30s %-15d %.1f%%%n",
                    description,
                    count,
                    (count * 100.0 / totalTransactions)
            );
        });

        return associationItemsVoList;
    }


    private static List<AssociationRulesVo> calculateRulesRules(List<Set<Integer>> transactions) {
        int totalTransactions = transactions.size();
        System.out.println("总样本数: " + totalTransactions + " 个学生\n");

        // ===================================================================
        // 一、项集支持度计算
        // ===================================================================
        Map<Set<Integer>, Integer> itemSetCounts = new HashMap<>();

        // 预定义所有可能的单项和双项组合
        List<Set<Integer>> possibleItemSets = Arrays.asList(
                Set.of(COURSE_HIGH), Set.of(COURSE_LOW),
                Set.of(EVAL_HIGH), Set.of(EVAL_LOW),
                Set.of(COURSE_HIGH, EVAL_HIGH),
                Set.of(COURSE_HIGH, EVAL_LOW),
                Set.of(COURSE_LOW, EVAL_HIGH),
                Set.of(COURSE_LOW, EVAL_LOW),
                Set.of(EVAL_HIGH, COURSE_HIGH),
                Set.of(EVAL_HIGH, COURSE_LOW),
                Set.of(EVAL_LOW, COURSE_HIGH),
                Set.of(EVAL_LOW, COURSE_LOW)
        );

        // 计算每个项集的支持度计数
        for (Set<Integer> itemSet : possibleItemSets) {
            int count = 0;
            for (Set<Integer> transaction : transactions) {
                if (transaction.containsAll(itemSet)) {
                    count++;
                }
            }
            itemSetCounts.put(itemSet, count);
        }

        // 打印支持度报表
        System.out.println("===================== 项集支持度分析 =====================");
        System.out.printf("%-30s %-15s %-15s%n", "项集描述", "出现次数", "支持度");
        itemSetCounts.forEach((itemSet, count) -> {
            String description = parseItemSet(itemSet);
            System.out.printf("%-30s %-15d %.1f%%%n",
                    description,
                    count,
                    (count * 100.0 / totalTransactions)
            );
        });

        // ===================================================================
        // 二、关联规则分析
        // ===================================================================
        System.out.println("\n\n===================== 关联规则分析 =====================");
        System.out.printf("%-35s %-10s %-10s %-10s%n", "规则", "支持度", "置信度", "提升度");

        // 分析所有可能的规则组合
        AssociationRulesVo r1 = analyzeRule(COURSE_HIGH, EVAL_HIGH, itemSetCounts, totalTransactions, "课程高分→评教高分");  // 课程高分→评教高分
        AssociationRulesVo r2 = analyzeRule(EVAL_HIGH, COURSE_HIGH, itemSetCounts, totalTransactions, "评教高分→课程高分");  // 评教高分→课程高分
        AssociationRulesVo r3 = analyzeRule(COURSE_LOW, EVAL_LOW, itemSetCounts, totalTransactions, "课程低分→评教低分");    // 课程低分→评教低分
        AssociationRulesVo r4 = analyzeRule(EVAL_LOW, COURSE_LOW, itemSetCounts, totalTransactions, "评教低分→课程低分");    // 评教低分→课程低分
        AssociationRulesVo r5 = analyzeRule(EVAL_LOW, COURSE_HIGH, itemSetCounts, totalTransactions, "评教低分→课程高分");   // 评教低分→课程高分
        AssociationRulesVo r6 = analyzeRule(COURSE_LOW, EVAL_HIGH, itemSetCounts, totalTransactions, "课程低分→评教高分");   // 课程低分→评教高分
        AssociationRulesVo r7 = analyzeRule(COURSE_HIGH, EVAL_LOW, itemSetCounts, totalTransactions, "课程高分→评教低分");   // 课程高分→评教低分
        AssociationRulesVo r8 = analyzeRule(EVAL_HIGH, COURSE_LOW, itemSetCounts, totalTransactions, "评教高分→课程低分");   // 评教高分→课程低分

        List<AssociationRulesVo> associationRulesVoList = new ArrayList<>();
        associationRulesVoList.add(r1);
        associationRulesVoList.add(r2);
        associationRulesVoList.add(r3);
        associationRulesVoList.add(r4);
        associationRulesVoList.add(r5);
        associationRulesVoList.add(r6);
        associationRulesVoList.add(r7);
        associationRulesVoList.add(r8);

        return associationRulesVoList;
    }

    private static List<AssociationRulesVo> calculateRulesRulesSup(List<Set<Integer>> transactions) {
        int totalTransactions = transactions.size();
        System.out.println("总样本数: " + totalTransactions + " 个学生\n");

        // ===================================================================
        // 一、项集支持度计算
        // ===================================================================
        Map<Set<Integer>, Integer> itemSetCounts = new HashMap<>();

        // 预定义所有可能的单项和双项组合
        List<Set<Integer>> possibleItemSets = Arrays.asList(
                Set.of(COURSE_HIGH), Set.of(COURSE_LOW),
                Set.of(EVAL_HIGH_TEA), Set.of(EVAL_LOW_TEA),
                Set.of(COURSE_HIGH, EVAL_HIGH_TEA),
                Set.of(COURSE_HIGH, EVAL_LOW_TEA),
                Set.of(COURSE_LOW, EVAL_HIGH_TEA),
                Set.of(COURSE_LOW, EVAL_LOW_TEA),
                Set.of(EVAL_HIGH_TEA, COURSE_HIGH),
                Set.of(EVAL_HIGH_TEA, COURSE_LOW),
                Set.of(EVAL_LOW_TEA, COURSE_HIGH),
                Set.of(EVAL_LOW_TEA, COURSE_LOW)
        );

        // 计算每个项集的支持度计数
        for (Set<Integer> itemSet : possibleItemSets) {
            int count = 0;
            for (Set<Integer> transaction : transactions) {
                if (transaction.containsAll(itemSet)) {
                    count++;
                }
            }
            itemSetCounts.put(itemSet, count);
        }

        // 打印支持度报表
        System.out.println("===================== 项集支持度分析 =====================");
        System.out.printf("%-30s %-15s %-15s%n", "项集描述", "出现次数", "支持度");
        itemSetCounts.forEach((itemSet, count) -> {
            String description = parseItemSet(itemSet);
            System.out.printf("%-30s %-15d %.1f%%%n",
                    description,
                    count,
                    (count * 100.0 / totalTransactions)
            );
        });

        // ===================================================================
        // 二、关联规则分析
        // ===================================================================
        System.out.println("\n\n===================== 关联规则分析 =====================");
        System.out.printf("%-35s %-10s %-10s %-10s%n", "规则", "支持度", "置信度", "提升度");

        // 分析所有可能的规则组合
        AssociationRulesVo r1 = analyzeRule(COURSE_HIGH, EVAL_HIGH_TEA, itemSetCounts, totalTransactions, "课程高分→评教高分");  // 课程高分→评教高分
        AssociationRulesVo r2 = analyzeRule(EVAL_HIGH_TEA, COURSE_HIGH, itemSetCounts, totalTransactions, "评教高分→课程高分");  // 评教高分→课程高分
        AssociationRulesVo r3 = analyzeRule(COURSE_LOW, EVAL_LOW_TEA, itemSetCounts, totalTransactions, "课程低分→评教低分");    // 课程低分→评教低分
        AssociationRulesVo r4 = analyzeRule(EVAL_LOW_TEA, COURSE_LOW, itemSetCounts, totalTransactions, "评教低分→课程低分");    // 评教低分→课程低分
        AssociationRulesVo r5 = analyzeRule(EVAL_LOW_TEA, COURSE_HIGH, itemSetCounts, totalTransactions, "评教低分→课程高分");   // 评教低分→课程高分
        AssociationRulesVo r6 = analyzeRule(COURSE_LOW, EVAL_HIGH_TEA, itemSetCounts, totalTransactions, "课程低分→评教高分");   // 课程低分→评教高分
        AssociationRulesVo r7 = analyzeRule(COURSE_HIGH, EVAL_LOW_TEA, itemSetCounts, totalTransactions, "课程高分→评教低分");   // 课程高分→评教低分
        AssociationRulesVo r8 = analyzeRule(EVAL_HIGH_TEA, COURSE_LOW, itemSetCounts, totalTransactions, "评教高分→课程低分");   // 评教高分→课程低分

        List<AssociationRulesVo> associationRulesVoList = new ArrayList<>();
        associationRulesVoList.add(r1);
        associationRulesVoList.add(r2);
        associationRulesVoList.add(r3);
        associationRulesVoList.add(r4);
        associationRulesVoList.add(r5);
        associationRulesVoList.add(r6);
        associationRulesVoList.add(r7);
        associationRulesVoList.add(r8);

        return associationRulesVoList;
    }

    private static List<AssociationRulesVo> calculateRulesRulesSupStu(List<Set<Integer>> transactions) {
        int totalTransactions = transactions.size();
        System.out.println("总样本数: " + totalTransactions + " 个学生\n");

        // ===================================================================
        // 一、项集支持度计算
        // ===================================================================
        Map<Set<Integer>, Integer> itemSetCounts = new HashMap<>();

        // 预定义所有可能的单项和双项组合
        List<Set<Integer>> possibleItemSets = Arrays.asList(
                Set.of(EVAL_HIGH), Set.of(EVAL_LOW),
                Set.of(EVAL_HIGH_TEA), Set.of(EVAL_LOW_TEA),
                Set.of(EVAL_HIGH, EVAL_HIGH_TEA),
                Set.of(EVAL_HIGH, EVAL_LOW_TEA),
                Set.of(EVAL_LOW, EVAL_HIGH_TEA),
                Set.of(EVAL_LOW, EVAL_LOW_TEA),
                Set.of(EVAL_HIGH_TEA, EVAL_HIGH),
                Set.of(EVAL_HIGH_TEA, EVAL_LOW),
                Set.of(EVAL_LOW_TEA, EVAL_HIGH),
                Set.of(EVAL_LOW_TEA, EVAL_LOW)
        );

        // 计算每个项集的支持度计数
        for (Set<Integer> itemSet : possibleItemSets) {
            int count = 0;
            for (Set<Integer> transaction : transactions) {
                if (transaction.containsAll(itemSet)) {
                    count++;
                }
            }
            itemSetCounts.put(itemSet, count);
        }

        // 打印支持度报表
        System.out.println("===================== 项集支持度分析 =====================");
        System.out.printf("%-30s %-15s %-15s%n", "项集描述", "出现次数", "支持度");
        itemSetCounts.forEach((itemSet, count) -> {
            String description = parseItemSet(itemSet);
            System.out.printf("%-30s %-15d %.1f%%%n",
                    description,
                    count,
                    (count * 100.0 / totalTransactions)
            );
        });

        // ===================================================================
        // 二、关联规则分析
        // ===================================================================
        System.out.println("\n\n===================== 关联规则分析 =====================");
        System.out.printf("%-35s %-10s %-10s %-10s%n", "规则", "支持度", "置信度", "提升度");

        // 分析所有可能的规则组合
        AssociationRulesVo r1 = analyzeRule(EVAL_HIGH, EVAL_HIGH_TEA, itemSetCounts, totalTransactions, "学生评教高分→督导评教高分");  // 课程高分→评教高分
        AssociationRulesVo r2 = analyzeRule(EVAL_HIGH_TEA, EVAL_HIGH, itemSetCounts, totalTransactions, "督导评教高分→学生评教高分");  // 评教高分→课程高分
        AssociationRulesVo r3 = analyzeRule(EVAL_LOW, EVAL_LOW_TEA, itemSetCounts, totalTransactions, "学生评教低分→督导评教低分");    // 课程低分→评教低分
        AssociationRulesVo r4 = analyzeRule(EVAL_LOW_TEA, EVAL_LOW, itemSetCounts, totalTransactions, "督导评教低分→学生评教低分");    // 评教低分→课程低分
        AssociationRulesVo r5 = analyzeRule(EVAL_LOW_TEA, EVAL_HIGH, itemSetCounts, totalTransactions, "督导评教低分→学生评教高分");   // 评教低分→课程高分
        AssociationRulesVo r6 = analyzeRule(EVAL_LOW, EVAL_HIGH_TEA, itemSetCounts, totalTransactions, "学生评教低分→督导评教高分");   // 课程低分→评教高分
        AssociationRulesVo r7 = analyzeRule(EVAL_HIGH, EVAL_LOW_TEA, itemSetCounts, totalTransactions, "学生评教高分→督导评教低分");   // 课程高分→评教低分
        AssociationRulesVo r8 = analyzeRule(EVAL_HIGH_TEA, EVAL_LOW, itemSetCounts, totalTransactions, "督导评教高分→学生评教低分");   // 评教高分→课程低分

        List<AssociationRulesVo> associationRulesVoList = new ArrayList<>();
        associationRulesVoList.add(r1);
        associationRulesVoList.add(r2);
        associationRulesVoList.add(r3);
        associationRulesVoList.add(r4);
        associationRulesVoList.add(r5);
        associationRulesVoList.add(r6);
        associationRulesVoList.add(r7);
        associationRulesVoList.add(r8);

        return associationRulesVoList;
    }

    private static List<AssociationRulesVo> calculateRulesRulesCourse(List<Set<Integer>> transactions) {
        int totalTransactions = transactions.size();
        System.out.println("总样本数: " + totalTransactions + " 个学生\n");

        // ===================================================================
        // 一、项集支持度计算
        // ===================================================================
        Map<Set<Integer>, Integer> itemSetCounts = new HashMap<>();

        // 预定义所有可能的单项和双项组合
        List<Set<Integer>> possibleItemSets = Arrays.asList(
                Set.of(HIGH1), Set.of(HIGH2),
                Set.of(HIGH3),
                Set.of(HIGH1, HIGH2),
                Set.of(HIGH1, HIGH3),
                Set.of(HIGH2, HIGH1),
                Set.of(HIGH2, HIGH3),
                Set.of(HIGH3, HIGH1),
                Set.of(HIGH3, HIGH2)
        );

        // 计算每个项集的支持度计数
        for (Set<Integer> itemSet : possibleItemSets) {
            int count = 0;
            for (Set<Integer> transaction : transactions) {
                if (transaction.containsAll(itemSet)) {
                    count++;
                }
            }
            itemSetCounts.put(itemSet, count);
        }

        // 打印支持度报表
        System.out.println("===================== 项集支持度分析 =====================");
        System.out.printf("%-30s %-15s %-15s%n", "项集描述", "出现次数", "支持度");
        itemSetCounts.forEach((itemSet, count) -> {
            String description = parseItemSet(itemSet);
            System.out.printf("%-30s %-15d %.1f%%%n",
                    description,
                    count,
                    (count * 100.0 / totalTransactions)
            );
        });

        // ===================================================================
        // 二、关联规则分析
        // ===================================================================
        System.out.println("\n\n===================== 关联规则分析 =====================");
        System.out.printf("%-35s %-10s %-10s %-10s%n", "规则", "支持度", "置信度", "提升度");

        // 分析所有可能的规则组合
        AssociationRulesVo r1 = analyzeRule(HIGH1, HIGH2, itemSetCounts, totalTransactions, "通识教育高分→学科教育高分");  // 课程高分→评教高分
        AssociationRulesVo r2 = analyzeRule(HIGH1, HIGH3, itemSetCounts, totalTransactions, "通识教育高分→专业课程高分");  // 评教高分→课程高分
        AssociationRulesVo r3 = analyzeRule(HIGH2, HIGH1, itemSetCounts, totalTransactions, "学科教育高分→通识教育高分");    // 课程低分→评教低分
        AssociationRulesVo r4 = analyzeRule(HIGH2, HIGH3, itemSetCounts, totalTransactions, "学科教育高分→专业课程高分");    // 评教低分→课程低分
        AssociationRulesVo r5 = analyzeRule(HIGH3, HIGH1, itemSetCounts, totalTransactions, "专业课程高分→通识教育高分");   // 评教低分→课程高分
        AssociationRulesVo r6 = analyzeRule(HIGH3, HIGH2, itemSetCounts, totalTransactions, "专业课程高分→学科教育高分");   // 课程低分→评教高分

        List<AssociationRulesVo> associationRulesVoList = new ArrayList<>();
        associationRulesVoList.add(r1);
        associationRulesVoList.add(r2);
        associationRulesVoList.add(r3);
        associationRulesVoList.add(r4);
        associationRulesVoList.add(r5);
        associationRulesVoList.add(r6);

        return associationRulesVoList;
    }


    // 关联规则分析工具方法
    private static AssociationRulesVo analyzeRule(int antecedent, int consequent,
                                    Map<Set<Integer>, Integer> itemSetCounts,
                                    int total, String rule) {
        Set<Integer> antecedentSet = Set.of(antecedent);
        Set<Integer> consequentSet = Set.of(consequent);
        Set<Integer> combinedSet = Set.of(antecedent, consequent);

        int supportAntecedent = itemSetCounts.getOrDefault(antecedentSet, 0);
        int supportConsequent = itemSetCounts.getOrDefault(consequentSet, 0);
        int supportBoth = itemSetCounts.getOrDefault(combinedSet, 0);

        // 支持度 = 规则共同出现次数 / 总样本数
        double support = (supportBoth * 100.0) / total;

        // 置信度 = 规则共同出现次数 / 前件出现次数
        double confidence = (supportAntecedent == 0) ? 0 :
                (supportBoth * 100.0) / supportAntecedent;

        // 提升度 = 置信度 / 后件支持度
        double lift = (supportConsequent == 0) ? 0 :
                confidence / (supportConsequent * 100.0 / total);

        System.out.printf("%-35s %-10.1f%% %-10.1f%% %-10.2f%n",
                parseItem(antecedent) + " → " + parseItem(consequent),
                support,
                confidence,
                lift
        );

        AssociationRulesVo associationRulesVo = new AssociationRulesVo();
        associationRulesVo.setFirstItem(antecedent);
        associationRulesVo.setSecondItem(consequent);
        associationRulesVo.setSupport(support);
        associationRulesVo.setConfidence(confidence);
        associationRulesVo.setLift(lift);
        associationRulesVo.setRule(rule);

        return associationRulesVo;
    }

    // ===================================================================
    // 辅助方法：项集转可读描述
    // ===================================================================
    private static String parseItemSet(Set<Integer> itemSet) {
        List<String> descriptions = new ArrayList<>();
        for (int item : itemSet) {
            descriptions.add(parseItem(item));
        }
        return String.join(" + ", descriptions);
    }

    private static String parseItem(int code) {
        switch (code) {
            case COURSE_HIGH: return "课程高分";
            case COURSE_LOW:  return "课程低分";
            case EVAL_HIGH:  return "评教高分";
            case EVAL_LOW:   return "评教低分";
            case EVAL_HIGH_TEA:  return "督导评教高分";
            case EVAL_LOW_TEA:   return "督导评教低分";
            default:         return "未知项";
        }
    }

    @Override
    public Response<List<AssociationItemsVo>> getAssociationItems(String classId, String subId, Double scoreCut, Double evaScoreCut) {
        List<ClusterScoreVo> clusterScoreVo = studentDao.getScoreSet(classId, subId);
        if(clusterScoreVo.isEmpty()) {
            return new Response<>(false, "Administration not found", null);
        }

        double[][] rawData = new double[clusterScoreVo.size()][2];
        for(int i = 0; i < clusterScoreVo.size() / 2; i++) {
            rawData[i][0] = clusterScoreVo.get(i * 2).getScore();
            rawData[i][1] = clusterScoreVo.get(i * 2 + 1).getEvaScore();
        }

        // 1. 数据二值化处理（更精确的编码）
        List<Set<Integer>> transactions = new ArrayList<>();
        for (double[] student : rawData) {
            Set<Integer> items = new HashSet<>();

            // 课程分数处理
            if(student[0] > scoreCut) {
                items.add(COURSE_HIGH);
            } else {
                items.add(COURSE_LOW);
            }

            // 评教分数处理
            if(student[1] > evaScoreCut) {
                items.add(EVAL_HIGH);
            } else {
                items.add(EVAL_LOW);
            }

            transactions.add(items);
        }

        // 2. 计算关联规则
        List<AssociationItemsVo> associationItemsVoList = calculateRulesItems(transactions);

        return new Response<>(true, "Success", associationItemsVoList);
    }

    // 课程与学生评教数据集
    private List<ClusterScoreVo> getAssociationRulesScoreSet(String classId, String subId) {
        List<ClusterScoreVo> clusterScoreVo = studentDao.getScoreSet(classId, subId);

        return clusterScoreVo;
    }

    // 课程与督导评教数据集
    private List<ClusterScoreVo> getAssociationRulesScoreSetSup(String subId) {
        List<ClusterScoreDto> clusterScoreDtoList = studentDao.getStudentSupScore(subId);

        if (clusterScoreDtoList.isEmpty()) { // 空值判定 为空则未查询到数据集 无需聚类分析
            return null;
        }

        List<ClusterScoreVo> clusterScoreVoList = new ArrayList<>();
        for (ClusterScoreDto clusterScoreDto : clusterScoreDtoList) {
            Double score = studentDao.getStudentScore(clusterScoreDto.getSubId(), clusterScoreDto.getTeacherId());
            if(score != null) {
                ClusterScoreVo clusterScoreVo = new ClusterScoreVo();
                clusterScoreVo.setScore(score);
                clusterScoreVo.setSupervisionScore(clusterScoreDto.getEvaScore());

                clusterScoreVoList.add(clusterScoreVo);
            }
        }

        return clusterScoreVoList;
    }

    // 学生评教与督导评教数据集
    private List<ClusterScoreVo> getAssociationRulesScoreSetSupStu(String subId) {
        List<ClusterScoreDto> clusterScoreDtoList = studentDao.getStudentSupScore(subId);

        if (clusterScoreDtoList.isEmpty()) { // 空值判定 为空则未查询到数据集 无需聚类分析
            return null;
        }

        List<ClusterScoreVo> clusterScoreVoList = new ArrayList<>();
        for (ClusterScoreDto clusterScoreDto : clusterScoreDtoList) {
            Double score = studentDao.getStudentEvaScoreOnly(clusterScoreDto.getSubId(), clusterScoreDto.getTeacherId());
            if(score != null) {
                ClusterScoreVo clusterScoreVo = new ClusterScoreVo();
                clusterScoreVo.setEvaScore(score);
                clusterScoreVo.setSupervisionScore(clusterScoreDto.getEvaScore());

                clusterScoreVoList.add(clusterScoreVo);
            }
        }

        return clusterScoreVoList;
    }

    // 课程体系成绩数据集
    public List<StudentPlatformScoreDto> getAssociationRulesScoreSetCourses(String classId) {
        List<StudentPlatformScoreDto> studentPlatformScoreDtos = studentDao.getAllStudentsOfOneClass(classId);
        if ( studentPlatformScoreDtos.isEmpty() )
            return null;

        for(int i = 0; i < studentPlatformScoreDtos.size(); i++) {
            studentPlatformScoreDtos.get(i).setDetail1Score((double) 0);
            studentPlatformScoreDtos.get(i).setDetail2Score((double) 0);
            studentPlatformScoreDtos.get(i).setDetail3Score((double) 0);
        }

        for(int i = 0; i < studentPlatformScoreDtos.size(); i++) {
            List<CourseScoreDto> courseScoreData = studentDao.getCourseScoreData(studentPlatformScoreDtos.get(i).getStudentId());

            int index1 = 0;
            int index2 = 0;
            int index3 = 0;

            for (CourseScoreDto courseScoreDto : courseScoreData) {
                switch (courseScoreDto.getPlatform()) {
                    case "通识教育课程": {
                        Double score = studentPlatformScoreDtos.get(i).getDetail1Score() + 0 + courseScoreDto.getSubScore();
                        studentPlatformScoreDtos.get(i).setDetail1Score(score);
                        ++index1;
                    }
                    break;
                    case "学科教育课程": {
                        Double score = studentPlatformScoreDtos.get(i).getDetail2Score() + 0 + courseScoreDto.getSubScore();
                        studentPlatformScoreDtos.get(i).setDetail2Score(score);
                        ++index2;
                    }
                    break;
                    case "专业教育课程": {
                        Double score = studentPlatformScoreDtos.get(i).getDetail3Score() + 0 + courseScoreDto.getSubScore();
                        studentPlatformScoreDtos.get(i).setDetail3Score(score);
                        ++index3;
                    }
                    break;
                }
            }

            if (index1 != 0)
                studentPlatformScoreDtos.get(i).setDetail1Score(studentPlatformScoreDtos.get(i).getDetail1Score() / index1);
            if (index2 != 0)
                studentPlatformScoreDtos.get(i).setDetail2Score(studentPlatformScoreDtos.get(i).getDetail2Score() / index2);
            if (index3 != 0)
                studentPlatformScoreDtos.get(i).setDetail3Score(studentPlatformScoreDtos.get(i).getDetail3Score() / index3);
        }

        System.out.println(studentPlatformScoreDtos);

        return studentPlatformScoreDtos;
    }

    // 课程与学生评教数据集关联规则分析
    @Override
    public Response<List<AssociationRulesVo>> getAssociationRules(String classId, String subId, Double scoreCut, Double evaScoreCut) {
        List<ClusterScoreVo> clusterScoreVo = getAssociationRulesScoreSet(classId, subId);
        if(clusterScoreVo.isEmpty()) {
            return new Response<>(false, "Administration not found", null);
        }

        double[][] rawData = new double[clusterScoreVo.size()][2];
        for(int i = 0; i < clusterScoreVo.size() / 2; i++) {
            rawData[i][0] = clusterScoreVo.get(i * 2).getScore();
            rawData[i][1] = clusterScoreVo.get(i * 2 + 1).getEvaScore();
        }

        // 1. 数据二值化处理（更精确的编码）
        List<Set<Integer>> transactions = new ArrayList<>();
        for (double[] student : rawData) {
            Set<Integer> items = new HashSet<>();

            // 课程分数处理
            if(student[0] > scoreCut) {
                items.add(COURSE_HIGH);
            } else {
                items.add(COURSE_LOW);
            }

            // 评教分数处理
            if(student[1] > evaScoreCut) {
                items.add(EVAL_HIGH);
            } else {
                items.add(EVAL_LOW);
            }

            transactions.add(items);
        }

        // 2. 计算关联规则
        List<AssociationRulesVo> associationRulesVoList = calculateRulesRules(transactions);

        return new Response<>(true, "Success", associationRulesVoList);
    }

    // 课程与督导评教数据集关联规则分析
    @Override
    public Response<List<AssociationRulesVo>> getAssociationRulesSup(String subId, Double scoreCut, Double supervisionScoreCut) {
        List<ClusterScoreVo> clusterScoreVo = getAssociationRulesScoreSetSup(subId);
        if(clusterScoreVo.isEmpty()) {
            return new Response<>(false, "Administration not found", null);
        }

        double[][] rawData = new double[clusterScoreVo.size()][2];
        for(int i = 0; i < clusterScoreVo.size() / 2; i++) {
            rawData[i][0] = clusterScoreVo.get(i * 2).getScore();
            rawData[i][1] = clusterScoreVo.get(i * 2 + 1).getSupervisionScore();
        }

        // 1. 数据二值化处理（更精确的编码）
        List<Set<Integer>> transactions = new ArrayList<>();
        for (double[] student : rawData) {
            Set<Integer> items = new HashSet<>();

            // 课程分数处理
            if(student[0] > scoreCut) {
                items.add(COURSE_HIGH);
            } else {
                items.add(COURSE_LOW);
            }

            // 评教分数处理
            if(student[1] > supervisionScoreCut) {
                items.add(EVAL_HIGH_TEA);
            } else {
                items.add(EVAL_LOW_TEA);
            }

            transactions.add(items);
        }

        // 2. 计算关联规则
        List<AssociationRulesVo> associationRulesVoList = calculateRulesRulesSup(transactions);

        return new Response<>(true, "Success", associationRulesVoList);
    }

    // 学生评教与督导评教数据集关联规则分析
    @Override
    public Response<List<AssociationRulesVo>> getAssociationRulesSupStu(String subId, Double evaScoreCut, Double supervisionScoreCut) {
        List<ClusterScoreVo> clusterScoreVo = getAssociationRulesScoreSetSupStu(subId);
        if(clusterScoreVo.isEmpty()) {
            return new Response<>(false, "Administration not found", null);
        }

        double[][] rawData = new double[clusterScoreVo.size()][2];
        for(int i = 0; i < clusterScoreVo.size() / 2; i++) {
            rawData[i][0] = clusterScoreVo.get(i * 2 + 1).getEvaScore();
            rawData[i][1] = clusterScoreVo.get(i * 2 + 1).getSupervisionScore();
        }

        // 1. 数据二值化处理（更精确的编码）
        List<Set<Integer>> transactions = new ArrayList<>();
        for (double[] student : rawData) {
            Set<Integer> items = new HashSet<>();

            // 学生评教分数处理
            if(student[0] > evaScoreCut) {
                items.add(EVAL_HIGH);
            } else {
                items.add(EVAL_LOW);
            }

            // 督导评教分数处理
            if(student[1] > supervisionScoreCut) {
                items.add(EVAL_HIGH_TEA);
            } else {
                items.add(EVAL_LOW_TEA);
            }

            transactions.add(items);
        }

        // 2. 计算关联规则
        List<AssociationRulesVo> associationRulesVoList = calculateRulesRulesSupStu(transactions);

        return new Response<>(true, "Success", associationRulesVoList);
    }

    // 不同课程成绩关联规则分析
    @Override
    public Response<List<AssociationRulesVo>> getAssociationRulesCourse(String classId, Double scoreCut) {
        List<StudentPlatformScoreDto> studentPlatformScoreDtos = getAssociationRulesScoreSetCourses(classId);
        System.out.println(studentPlatformScoreDtos);
        if(studentPlatformScoreDtos.isEmpty()) {
            return new Response<>(false, "Administration not found", null);
        }

        double[][] rawData = new double[studentPlatformScoreDtos.size()][3];
        for(int i = 0; i < studentPlatformScoreDtos.size(); i++) {
            rawData[i][0] = studentPlatformScoreDtos.get(i).getDetail1Score();
            rawData[i][1] = studentPlatformScoreDtos.get(i).getDetail2Score();
            rawData[i][2] = studentPlatformScoreDtos.get(i).getDetail3Score();
        }

        // 1. 数据二值化处理（更精确的编码）
        List<Set<Integer>> transactions = new ArrayList<>();
        for (double[] student : rawData) {
            Set<Integer> items = new HashSet<>();

            // 通识教育分数处理
            if(student[0] > scoreCut) {
                items.add(HIGH1);
            }

            // 学科教育分数处理
            if(student[1] > scoreCut) {
                items.add(HIGH2);
            }

            // 专业课程分数处理
            if(student[2] > scoreCut) {
                items.add(HIGH3);
            }

            transactions.add(items);
        }

        // 2. 计算关联规则
        List<AssociationRulesVo> associationRulesVoList = calculateRulesRulesCourse(transactions);

        return new Response<>(true, "Success", associationRulesVoList);
    }

    /**
     * 课程与学生评教分数集合  用于聚类
     */
    @Override
    public Response<List<ClusterScoreVo>> getScoreSet(String classId, String subId) {
        List<ClusterScoreVo> clusterScoreVo = studentDao.getScoreSet(classId, subId);

        if (!clusterScoreVo.isEmpty()) {
            return new Response<>(true, "Success", clusterScoreVo);
        } else {
            return new Response<>(false, "Administration not found", null);
        }
    }

    /**
     * 课程与督导评教分数集合  用于聚类
     */
    @Override
    public Response<List<ClusterScoreVo>> getScoreSetSup(String subId) {
        List<ClusterScoreDto> clusterScoreDtoList = studentDao.getStudentSupScore(subId);

        if (clusterScoreDtoList.isEmpty()) { // 空值判定 为空则未查询到数据集 无需聚类分析
            return new Response<>(false, "Administration not found", null);
        }

        List<ClusterScoreVo> clusterScoreVoList = new ArrayList<>();
        for (ClusterScoreDto clusterScoreDto : clusterScoreDtoList) {
            Double score = studentDao.getStudentScore(clusterScoreDto.getSubId(), clusterScoreDto.getTeacherId());
            if(score != null) {
                ClusterScoreVo clusterScoreVo = new ClusterScoreVo();
                clusterScoreVo.setScore(score);
                clusterScoreVo.setSupervisionScore(clusterScoreDto.getEvaScore());

                clusterScoreVoList.add(clusterScoreVo);
            }
        }

        if (clusterScoreVoList.isEmpty()) {
            return new Response<>(false, "Administration not found", null);
        }

        return new Response<>(true, "Success", clusterScoreVoList);
    }

    /**
     * 学生评教与督导评教分数集合  用于聚类
     */
    @Override
    public Response<List<ClusterScoreVo>> getScoreSetSupStu(String subId) {
        List<ClusterScoreDto> clusterScoreDtoList = studentDao.getStudentSupScore(subId);

        if (clusterScoreDtoList.isEmpty()) { // 空值判定 为空则未查询到数据集 无需聚类分析
            return new Response<>(false, "Administration not found", null);
        }

        List<ClusterScoreVo> clusterScoreVoList = new ArrayList<>();
        for (ClusterScoreDto clusterScoreDto : clusterScoreDtoList) {
            Double score = studentDao.getStudentEvaScoreOnly(clusterScoreDto.getSubId(), clusterScoreDto.getTeacherId());
            if(score != null) {
                ClusterScoreVo clusterScoreVo = new ClusterScoreVo();
                clusterScoreVo.setEvaScore(score);
                clusterScoreVo.setSupervisionScore(clusterScoreDto.getEvaScore());

                clusterScoreVoList.add(clusterScoreVo);
            }
        }

        if (clusterScoreVoList.isEmpty()) {
            return new Response<>(false, "Administration not found", null);
        }

        return new Response<>(true, "Success", clusterScoreVoList);
    }
}
